package com.vasthu.gui;

import com.vasthu.api.domain.Role;
import com.vasthu.api.domain.User;
import com.vasthu.api.service.RoleManagerService;
import com.vasthu.api.service.UserManagerService;
import com.vasthu.core.service.RoleManagerServiceImpl;
import com.vasthu.core.service.UserManagerServiceImpl;
import com.vasthu.gui.utility.SpringUtilities;
import com.vasthu.gui.utility.VstGuiUtils;
import com.vasthu.utility.DateTimeUtils;
import com.vasthu.utility.HashUtil;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;

public class VstUserDataForm extends JDialog {

    private long userId;
    private JLabel lUserTitle;
    private JLabel lUserName;
    private JLabel lUserPhone;
    private JLabel lUserEmail;
    private JLabel lUserAddress;
    private JLabel lUserCity;
    private JLabel lUserUsername;
    private JLabel lUserPassword;
    private JLabel lUserRetypePassword;
    private JLabel lUserNic;
    private JLabel lUserRole;
    private JLabel lUserSalary;
    private JLabel lUserDob;
    private JTextField tUserName;
    private JTextField tUserPhone;
    private JTextField tUserEmail;
    private JTextField tUserAddress;
    private JTextField tUserCity;
    private JTextField tUserUsername;
    private JPasswordField tUserPassword;
    private JPasswordField tUserRetypePassword;
    private JTextField tUserNic;
    private JComboBox tUserRole;
    //private JFormattedTextField tUserDob;
    private JComboBox tYear;
    private JComboBox tMonth;
    private JComboBox tDate;
    private JFormattedTextField tUserSalary;
    private JButton changePassword;
    private Component spacer;
    private JButton addUser;
    private JButton updateUser;
    private JButton deleteUser;
    private JButton cancelButton;
    private NumberFormat salaryFormat;
    private int tableRow;
    private VstTableCallBack callback;
    private long currentUserId;
    private UserManagerService userManagerService = null;
    private RoleManagerService roleManagerService = null;

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public long getUserId() {
        return userId;
    }

    public VstUserDataForm(int mode, int tableRow, VstTableCallBack callback) {
        userManagerService = new UserManagerServiceImpl();
        roleManagerService = new RoleManagerServiceImpl();

        initUi();
        this.tableRow = tableRow;
        this.callback = callback;
        currentUserId = -1;

        switch (mode) {
            case VstGuiConstants.USER_FORM_ADD:
                addUser.setVisible(true);
                updateUser.setVisible(false);
                deleteUser.setVisible(false);
                changePassword.setVisible(false);
                spacer.setVisible(false);
                break;
            case VstGuiConstants.USER_FORM_UPDATE:
                addUser.setVisible(false);
                updateUser.setVisible(true);
                deleteUser.setVisible(true);
                changePassword.setVisible(true);
                lUserUsername.setEnabled(false);
                tUserUsername.setEnabled(false);
                lUserPassword.setEnabled(false);
                tUserPassword.setEnabled(false);
                lUserRetypePassword.setEnabled(false);
                tUserRetypePassword.setEnabled(false);
                break;
            default:
                break;
        }

    }

    private void initUi() {
        setTitle("User");

        lUserTitle = new JLabel("User", JLabel.CENTER);
        lUserTitle.setFont(new Font("Monospaced 12", Font.BOLD, 16));

        lUserName = new JLabel("Name : ", JLabel.TRAILING);
        lUserName.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserPhone = new JLabel("Phone : ", JLabel.TRAILING);
        lUserPhone.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserEmail = new JLabel("E-mail : ", JLabel.TRAILING);
        lUserEmail.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserAddress = new JLabel("Address : ", JLabel.TRAILING);
        lUserAddress.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserCity = new JLabel("City : ", JLabel.TRAILING);
        lUserCity.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserUsername = new JLabel("Username : ", JLabel.TRAILING);
        lUserUsername.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserPassword = new JLabel("Password : ", JLabel.TRAILING);
        lUserPassword.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserRetypePassword = new JLabel("Re-type Password : ", JLabel.TRAILING);
        lUserRetypePassword.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserNic = new JLabel("NIC : ", JLabel.TRAILING);
        lUserNic.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserDob = new JLabel("DOB : ", JLabel.TRAILING);
        lUserDob.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserRole = new JLabel("Roles : ", JLabel.TRAILING);
        lUserRole.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        lUserSalary = new JLabel("Salary : ", JLabel.TRAILING);
        lUserSalary.setFont(new Font("Monospaced 12", Font.PLAIN, 12));

        tUserName = new JTextField();
        tUserName.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserName.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserPhone = new JTextField();
        tUserPhone.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserPhone.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserEmail = new JTextField();
        tUserEmail.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserEmail.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserAddress = new JTextField();
        tUserAddress.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserAddress.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserCity = new JTextField();
        tUserCity.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserCity.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserUsername = new JTextField();
        tUserUsername.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserUsername.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserPassword = new JPasswordField();
        tUserPassword.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserPassword.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserRetypePassword = new JPasswordField();
        tUserRetypePassword.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserRetypePassword.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserNic = new JTextField();
        tUserNic.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserNic.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        //tUserDob = new JFormattedTextField(new SimpleDateFormat("yyyy-MM-dd"));
        //tUserDob.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        //tUserDob.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));

        tYear = new JComboBox();
        tYear.setPreferredSize(new Dimension(100, 25));
        tYear.setMaximumSize(new Dimension(100, 25));
        tMonth = new JComboBox(new DateFormatSymbols().getMonths());
        tMonth.removeItem("");
        tMonth.setPreferredSize(new Dimension(100, 25));
        tMonth.setMaximumSize(new Dimension(100, 25));
        tDate = new JComboBox();
        tDate.setPreferredSize(new Dimension(80, 25));
        tDate.setMaximumSize(new Dimension(80, 25));

        int year = Calendar.getInstance().get(Calendar.YEAR);
        for (int i = 1930; i <= year; i++) {
            tYear.addItem(String.valueOf(i));
        }

        tMonth.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                String year = (String) tYear.getSelectedItem();
                String month = (String) tMonth.getSelectedItem();
                int maxDate = VstGuiUtils.getMaxDateForYearAndMonth(year, month);

                tDate.removeAllItems();
                for (int i = 1; i <= maxDate; ++i) {
                    tDate.addItem(i);
                }
            }
        });

        int maxDate = VstGuiUtils.getMaxDateForYearAndMonth("1930", "January");
        for (int i = 1; i <= maxDate; ++i) {
            tDate.addItem(i);
        }

        JPanel dobPanel = new JPanel();
        dobPanel.setLayout(new BoxLayout(dobPanel, BoxLayout.X_AXIS));
        dobPanel.add(tYear);
        dobPanel.add(tMonth);
        dobPanel.add(tDate);

        tUserRole = new JComboBox();
        java.util.List<String> roleNames = roleManagerService.getAllRoleNames();

        for (String name : roleNames) {
            tUserRole.addItem(name);
        }

        tUserRole.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserRole.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
        salaryFormat = new DecimalFormat("###,###,###.00"); //NumberFormat.getNumberInstance();
        tUserSalary = new JFormattedTextField(salaryFormat /*
                 * new DecimalFormat("###,###,###.00")
                 */);
        tUserSalary.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tUserSalary.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));

        changePassword = new JButton("Change Password");
        changePassword.setPreferredSize(new Dimension(150, 40));
        changePassword.setMaximumSize(new Dimension(150, 40));
        addUser = new JButton("ADD");
        addUser.setPreferredSize(new Dimension(100, 40));
        addUser.setMaximumSize(new Dimension(100, 40));
        updateUser = new JButton("UPDATE");
        updateUser.setPreferredSize(new Dimension(100, 40));
        updateUser.setMaximumSize(new Dimension(100, 40));
        deleteUser = new JButton("DELETE");
        deleteUser.setPreferredSize(new Dimension(100, 40));
        deleteUser.setMaximumSize(new Dimension(100, 40));
        cancelButton = new JButton("CANCEL");
        cancelButton.setPreferredSize(new Dimension(100, 40));
        cancelButton.setMaximumSize(new Dimension(100, 40));

        JPanel basePanel = new JPanel();
        basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.Y_AXIS));
        basePanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 10));

        JPanel topPanel = new JPanel(new FlowLayout());
        topPanel.add(lUserTitle);
        topPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 30));
        topPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30));
        basePanel.add(topPanel);

        JPanel dataPanel = new JPanel(new SpringLayout());

        dataPanel.add(lUserName);
        dataPanel.add(tUserName);
        dataPanel.add(lUserNic);
        dataPanel.add(tUserNic);
        dataPanel.add(lUserPhone);
        dataPanel.add(tUserPhone);
        dataPanel.add(lUserEmail);
        dataPanel.add(tUserEmail);
        dataPanel.add(lUserAddress);
        dataPanel.add(tUserAddress);
        dataPanel.add(lUserCity);
        dataPanel.add(tUserCity);
        dataPanel.add(lUserDob);
        dataPanel.add(dobPanel);
        //dataPanel.add(tUserDob);
        dataPanel.add(lUserRole);
        dataPanel.add(tUserRole);
        dataPanel.add(lUserSalary);
        dataPanel.add(tUserSalary);
        dataPanel.add(lUserUsername);
        dataPanel.add(tUserUsername);
        dataPanel.add(lUserPassword);
        dataPanel.add(tUserPassword);
        dataPanel.add(lUserRetypePassword);
        dataPanel.add(tUserRetypePassword);
        basePanel.add(dataPanel);

        SpringUtilities.makeCompactGrid(dataPanel,
                12, 2, //rows, cols
                8, 8, //initialX, initialY
                0, 8);

        basePanel.add(Box.createVerticalGlue());

        JPanel mainButtonPanel = new JPanel();
        mainButtonPanel.setLayout(new BoxLayout(mainButtonPanel, BoxLayout.X_AXIS));
        mainButtonPanel.add(changePassword);
        mainButtonPanel.add(Box.createHorizontalGlue());
        mainButtonPanel.add(addUser);
        mainButtonPanel.add(updateUser);
        spacer = Box.createRigidArea(new Dimension(10, 10));
        mainButtonPanel.add(spacer);
        mainButtonPanel.add(deleteUser);
        mainButtonPanel.add(Box.createRigidArea(new Dimension(10, 10)));
        mainButtonPanel.add(cancelButton);
        basePanel.add(mainButtonPanel);

        add(basePanel);

        initActions();

        setModalityType(ModalityType.APPLICATION_MODAL);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setMinimumSize(new Dimension(600, 550));
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation((screen.width - 600) / 2, (screen.height - 550) / 2);
    }

    private void initActions() {

        addUser.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                User user = getUser();
                userManagerService.insertUser(user);
            }
        });

        updateUser.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
            }
        });

        deleteUser.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                userManagerService.deleteUserById(currentUserId);
                // DB row must be deleted before this line
                callback.rowDeleted(tableRow);
            }
        });

        cancelButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                close();
            }
        });
    }

    public User getUser() {
        User user = new User();

        user.setUserName(tUserName.getText());
        user.setUserPhone(tUserPhone.getText());
        user.setUserEmail(tUserEmail.getText());
        user.setUserAddress(tUserAddress.getText());
        user.setUserCity(tUserCity.getText());
        user.setUserUserName(tUserUsername.getText());
        user.setUserNIC(tUserNic.getText());
        user.setUserPassword(HashUtil.hashString(new String(tUserPassword.getPassword())));
        String roleName = (String) tUserRole.getSelectedItem();
        Role role = roleManagerService.getRoleByName(roleName);
        user.setUserRoleId(role.getRoleId());

        float salary = ((Number) tUserSalary.getValue()).floatValue();
        user.setUserSalary(salary);

        int year = Integer.parseInt((String) tYear.getSelectedItem());
        int month = VstGuiUtils.getMonthValue((String) tMonth.getSelectedItem());
        assert (month != -1);
        int day = (Integer) tDate.getSelectedItem();

        if (month != -1 && month < 12 && day > 0 && day < 32 && year > 1900) {
            Date dob = DateTimeUtils.getDateFromISO8601String(year + "-" + (month+1) + "-" + day);
            user.setUserDob(dob);
        }

        return user;
    }

    public void populate(User user) {
        if (user == null) {
            return;
        }

        currentUserId = user.getUserId();
        tUserName.setText(user.getUserName());
        tUserPhone.setText(user.getUserPhone());
        tUserEmail.setText(user.getUserEmail());
        tUserAddress.setText(user.getUserAddress());
        tUserCity.setText(user.getUserCity());
        tUserUsername.setText(user.getUserUserName());
        tUserNic.setText(user.getUserNIC());
        tUserSalary.setValue(user.getUserSalary());

        Role role = roleManagerService.getRoleById(user.getUserRoleId());
        if (role != null) {
            tUserRole.setSelectedItem(role.getRoleName());
        }

        Calendar cal = Calendar.getInstance();
        Date date = user.getUserDob();
        if (date != null) {
            cal.setTime(date);
            int yName = cal.get(Calendar.YEAR);
            tYear.setSelectedItem(String.valueOf(yName));
            String mName = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH);
            tMonth.setSelectedItem(mName);
        }
    }

    private void close() {
        dispose();
    }
}